/* eslint-disable no-param-reassign */
import { computed, defineComponent, PropType, ref, Ref, watch } from 'vue';
import { useNamespace } from '@ibiz-template/vue3-util';
import { IDEFormItem } from '@ibiz/model-core';
import { FormSearchItemController } from './controller';
import './form-search-item.scss';

export const FormSearchItem = defineComponent({
  name: 'FormSearchItem',
  props: {
    modelData: {
      type: Object as PropType<IDEFormItem>,
      required: true,
    },
    controller: {
      type: FormSearchItemController,
      required: true,
    },
  },
  setup(props) {
    const ns = useNamespace('form-search-item');
    const c = props.controller;
    const editor = props.modelData.editor;
    const expand: Ref<boolean> = ref(true);
    const selectItems: Ref<IData[]> = ref([]);
    const searchValue: Ref<string> = ref('');
    const items: Ref<IData[]> = ref([]);

    const init = () => {
      items.value = c.remoteDatas;
    };

    init();

    const changeExpand = () => {
      expand.value = !expand.value;
    };

    const groupChangeExpand = (item: IData) => {
      item.expand = !item.expand;
    };

    const isSelected = (data: IData) => {
      const selected = selectItems.value.find(
        (item: IData) => item[c.keyName] === data[c.keyName],
      );
      return selected;
    };

    const initGroupExport = () => {
      if (selectItems.value.length > 0) {
        items.value.forEach(item => {
          if (item.isGroup) {
            const selected = item.children.filter((child: IData) => {
              return selectItems.value.find(
                select => select[c.keyName] === child[c.keyName],
              );
            });
            if (selected && selected.length > 0) {
              item.expand = true;
            }
          }
        });
      }
    };

    watch(
      () => c.value,
      newValue => {
        selectItems.value = [];
        if (newValue) {
          const selects: string[] = (newValue as string).split(',');
          selects.forEach((selected: string) => {
            const tempObj = {
              [c.keyName]: selected,
            };
            let tempArray: IData[] = [];
            if (c.editorParams.codeListGroup) {
              if (items.value && items.value.length > 0) {
                items.value.forEach((item: IData) => {
                  tempArray.push(...item.children);
                });
              }
            } else {
              tempArray = items.value;
            }
            if (tempArray.length > 0) {
              const data = tempArray.find(item => {
                return item[c.keyName] === selected;
              });
              if (data) {
                Object.assign(tempObj, data);
              }
            }
            selectItems.value.push(tempObj);
          });
        }
        initGroupExport();
        c.setSelectItems(selectItems.value);
      },
      {
        immediate: true,
        deep: true,
      },
    );

    const onSelect = (selected: IData) => {
      const index = selectItems.value.findIndex(
        (item: IData) => selected[c.keyName] === item[c.keyName],
      );
      if (index !== -1) {
        selectItems.value.splice(index, 1);
      } else {
        selectItems.value.push(selected);
      }
      c.setSelectItems(selectItems.value);
      c.handleSelectData(selectItems.value);
    };

    const data = computed(() => {
      return items.value.filter(item => {
        if (searchValue.value) {
          if (item.isGroup) {
            return (item.children as IData[]).find((child: IData) =>
              child[c.textName].includes(searchValue.value),
            );
          }
          return item[c.textName].includes(searchValue.value);
        }
        return true;
      });
    });

    const renderItem = (item: IData) => {
      return (
        <div
          class={{
            [ns.e('content-item')]: true,
            [ns.em('content-item', 'selected')]: isSelected(item),
          }}
          key={item[c.keyName]}
          title={item[c.textName]}
          onClick={() => onSelect(item)}
        >
          <div class={ns.e('content-item-left')}>{item[c.textName]}</div>
          <div class={ns.e('content-item-right')}>{item.total_count}</div>
        </div>
      );
    };

    const renderGroup = (item: IData) => {
      return (
        <div class={ns.e('content-group')} key={item.id} title={item.text}>
          <div
            class={ns.e('content-group-header')}
            onClick={() => groupChangeExpand(item)}
          >
            <div class={ns.e('group-header-left')}>{item.text}</div>
            <div class={ns.e('group-header-right')}>
              {item.expand ? (
                <ion-icon name='chevron-down-outline'></ion-icon>
              ) : (
                <ion-icon name='chevron-forward-outline'></ion-icon>
              )}
            </div>
          </div>
          {item.expand && (
            <div class={ns.e('content-group-items')}>
              {(item.children as IData[]).map(child => {
                return renderItem(child);
              })}
            </div>
          )}
        </div>
      );
    };

    const renderContent = () => {
      return data.value.map(item => {
        if (item.isGroup) {
          return renderGroup(item);
        }
        return renderItem(item);
      });
    };

    return {
      ns,
      c,
      items,
      expand,
      changeExpand,
      editor,
      searchValue,
      onSelect,
      isSelected,
      renderContent,
    };
  },
  render() {
    if (!this.c.state.visible) {
      return null;
    }
    return (
      <div
        class={[
          this.ns.b(),
          this.ns.m(this.modelData.id),
          ...this.controller.containerClass,
        ]}
      >
        <div class={this.ns.e('header')}>
          <div class={this.ns.e('header-icon')}>
            <i class={this.modelData.sysImage?.cssClass}></i>
          </div>
          <div class={this.ns.e('header-title')}>{this.modelData.caption}</div>
          <div class={this.ns.e('header-expand')}>
            {this.expand ? (
              <span onClick={() => this.changeExpand()}>
                <ion-icon name='remove-outline'></ion-icon>
              </span>
            ) : (
              <span onClick={() => this.changeExpand()}>
                <ion-icon name='add-outline'></ion-icon>
              </span>
            )}
          </div>
        </div>
        {this.editor && this.expand && (
          <div class={this.ns.e('content')}>
            {this.c.editorParams?.isSearch && (
              <div class={this.ns.e('content-search')}>
                <el-input
                  v-model={this.searchValue}
                  placeholder={this.editor.placeHolder}
                >
                  {{
                    prefix: () => {
                      return <ion-icon name='search'></ion-icon>;
                    },
                  }}
                </el-input>
              </div>
            )}
            {this.renderContent()}
          </div>
        )}
      </div>
    );
  },
});
export default FormSearchItem;
